package io.shallwe.common.config;

import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.json.FastJsonFactory;
import com.jfinal.json.JFinalJsonFactory;
import com.jfinal.json.JacksonFactory;
import com.jfinal.kit.Prop;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.dialect.PostgreSqlDialect;
import com.jfinal.plugin.cron4j.Cron4jPlugin;
import com.jfinal.template.Engine;
import com.jfinal.server.undertow.UndertowServer;
import com.jfinal.plugin.druid.DruidPlugin;
import com.jfinal.plugin.ehcache.EhCachePlugin;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.wall.WallFilter;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.dialect.SqlServerDialect;
import com.jfinal.render.ViewType;

import io.shallwe._admin.permission.PermissionDirective;
import io.shallwe._admin.role.RoleDirective;
import io.shallwe.common.interceptor.LoginSessionInterceptor;
import io.shallwe.common.model._MappingKitForPg;
import io.shallwe.common.model._MappingKitForSqlServer;
import io.shallwe.scanner.auto.AutoScannerStarter;
import io.shallwe.scanner.manual.*;
import io.shallwe.task.LineInfoUpdatePlugIn;
import io.shallwe.task.ParameterCollectPlugin;

public class MainConfig extends JFinalConfig {
	/**
	 * 将全局配置提出来 方便其他地方重用
	 */
	private static Prop p;
	private WallFilter wallFilter;
	
	private ManualScannerStarter1 manualScannerStarter1=null;
	private ManualScannerStarter2 manualScannerStarter2=null;
	private ManualScannerStarter3 manualScannerStarter3=null;
	private ManualScannerStarter4 manualScannerStarter4=null;
	private ManualScannerStarter5 manualScannerStarter5=null;
	private ManualScannerStarter6 manualScannerStarter6=null;
	private AutoScannerStarter autoScanner=null;
	/**
	 * 配置JFinal常量
	 */
	@Override
	public void configConstant(Constants me) {
		//读取数据库配置文件
		loadConfig();
		//设置当前是否为开发模式
		me.setDevMode(p.getBoolean("devMode"));
		//设置默认上传文件保存路径 getFile等使用
		me.setBaseUploadPath("upload/temp/");
		//设置上传最大限制尺寸
		//me.setMaxPostSize(1024*1024*10);
		//设置默认下载文件路径 renderFile使用
		me.setBaseDownloadPath("download");
		//设置默认视图类型
		me.setViewType(ViewType.JFINAL_TEMPLATE);
		//设置404渲染视图
		me.setError404View("404.html");
		
		//设置启用依赖注入
		me.setInjectDependency(true);
	}
	/**
	 * 配置项目路由
	 * 路由拆分到 FrontRutes 与 AdminRoutes 之中配置的好处：
	 * 1：可分别配置不同的 baseViewPath 与 Interceptor
	 * 2：避免多人协同开发时，频繁修改此文件带来的版本冲突
	 * 3：避免本文件中内容过多，拆分后可读性增强
	 * 4：便于分模块管理路由
	 */
	@Override
	public void configRoute(Routes me) {
		//推荐拆分方式 如果需要就解开注释 创建对应的 Routes
		//配置后台管理系统路由
		me.add(new AdminRoutes());
		me.add(new FrontRoutes());
	}
	// 先加载开发环境配置，再追加生产环境的少量配置覆盖掉开发环境配置
	static void loadConfig() {
		if (p == null) {
			p = PropKit.use("config.properties").appendIfExists("config-pro.properties");
		}
	}
	/**
	 * 获取数据库插件
	 * 抽取成独立的方法，便于重用该方法，减少代码冗余
	 */
	public static DruidPlugin getDruidPlugin() {
		loadConfig();
		return new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p.get("password"));
	}
	/**
	 * 配置JFinal插件
	 * 数据库连接池
	 * ActiveRecordPlugin
	 * 缓存
	 * 定时任务
	 * 自定义插件
	 */
	@Override
	public void configPlugin(Plugins me) {
		loadConfig();
		//配置数据库连接池插件
		DruidPlugin dbPlugin=getDruidPlugin();
		wallFilter = new WallFilter();
		wallFilter.setDbType("sqlserver");
		dbPlugin.addFilter(wallFilter);
		dbPlugin.addFilter(new StatFilter());

		ActiveRecordPlugin arp=new ActiveRecordPlugin(dbPlugin);
		arp.setShowSql(false);
		arp.setDialect(new SqlServerDialect());
		dbPlugin.setDriverClass("com.microsoft.sqlserver.jdbc.SQLServerDriver");
		arp.getEngine().setToClassPathSourceFactory();
		arp.getEngine().addSharedObject("sk",new StrKit());
		arp.addSqlTemplate("/sql/_sqlserver_sqls.sql");
		
		_MappingKitForSqlServer.mapping(arp);


		String pgUrl=p.get("pgUrl");
		String pgUserName=p.get("pgUserName");
		String pgPassword=p.get("pgPassword");
		DruidPlugin pgDruidPlugin = new DruidPlugin(pgUrl,pgUserName,pgPassword);
		pgDruidPlugin.setDriverClass("org.postgresql.Driver");

		ActiveRecordPlugin pgActiveRecordPlugin= new ActiveRecordPlugin("pg",pgDruidPlugin);
		pgActiveRecordPlugin.setShowSql(false);
		pgActiveRecordPlugin.setDialect(new PostgreSqlDialect());
		pgActiveRecordPlugin.getEngine().setToClassPathSourceFactory();
		pgActiveRecordPlugin.getEngine().addSharedObject("sk",new StrKit());
		pgActiveRecordPlugin.addSqlTemplate("/sql/_postgresql_sql.sql");
		_MappingKitForPg.mapping(pgActiveRecordPlugin);


		//添加到插件列表中
		me.add(dbPlugin);
		me.add(arp);

		me.add(pgDruidPlugin);
		me.add(pgActiveRecordPlugin);

		me.add(new EhCachePlugin());
		me.add(new Cron4jPlugin(p));

		me.add(new ParameterCollectPlugin());
		me.add(new LineInfoUpdatePlugIn());
	}
	/**
	 * 配置全局拦截器
	 */
	@Override
	public void configInterceptor(Interceptors me) {
		me.add(new LoginSessionInterceptor());
	}
	/**
	 * 配置全局处理器
	 */
	@Override
	public void configHandler(Handlers me) {
		me.add(new ContextPathHandler("ctx"));
	}
	/**
	 * 项目启动后调用
	 */
	@Override
	public void onStart() {
		wallFilter.getConfig().setSelectUnionCheck(false);
		manualScannerStarter1=new ManualScannerStarter1();
		manualScannerStarter1.start();
		manualScannerStarter2=new ManualScannerStarter2();
		manualScannerStarter2.start();
		manualScannerStarter3=new ManualScannerStarter3();
		manualScannerStarter3.start();

		manualScannerStarter4=new ManualScannerStarter4();
		manualScannerStarter4.start();
		manualScannerStarter5=new ManualScannerStarter5();
		manualScannerStarter5.start();
		manualScannerStarter6=new ManualScannerStarter6();
		manualScannerStarter6.start();

		autoScanner=new AutoScannerStarter();
		autoScanner.start();
	}
	
	@Override
	public void onStop() {
		if(manualScannerStarter1!=null) {
			manualScannerStarter1.stop();
		}
		if(manualScannerStarter2!=null) {
			manualScannerStarter2.stop();
		}
		if(manualScannerStarter3!=null) {
			manualScannerStarter3.stop();
		}

		if(manualScannerStarter4!=null) {
			manualScannerStarter4.stop();
		}
		if(manualScannerStarter5!=null) {
			manualScannerStarter5.stop();
		}
		if(manualScannerStarter6!=null) {
			manualScannerStarter6.stop();
		}

		if(autoScanner!=null) {
			autoScanner.stop();
		}
	}
	
	/**
	 * 配置模板引擎 
	 */
	@Override
	public void configEngine(Engine me) {
		me.setDevMode(p.getBoolean("engineDevMode", false));
		
		me.addDirective("role", RoleDirective.class);
		me.addDirective("permission", PermissionDirective.class);
		me.addDirective("perm", PermissionDirective.class);
		
		me.addSharedFunction("/_view/common/_layout.html");
		me.addSharedFunction("/_view/common/_paginate.html");
	}
	
	public static void main(String[] args) {
		UndertowServer.create(MainConfig.class,"undertow.properties").start();
	}
}

